﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Net;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.Xml;
using System.Web;
using ScottLane.MediaFeeder.ObjectModel;

// download: http://www.vistax64.com/indigo/72738-file-download-through-wcf-rest.html
// podcast: http://robertseder.spaces.live.com/blog/cns!587F478B9240C01E!264.entry
// podcast: http://www.podcast411.com/howto_1.html

namespace ScottLane.MediaFeeder.WebService
{
    /// <summary>
    /// Partial class of MediaService that implements the Song related methods.
    /// </summary>
    public partial class MediaService : IMediaService
    {
        /// <summary>
        /// Gets a feed of the specified song.
        /// </summary>
        /// <param name="songID">The song identifier.</param>
        /// <returns>The feed.</returns>
        public SyndicationFeedFormatter GetSong(string songID)
        {
            string decodedSongID = HttpUtility.UrlDecode(songID);

            if (!Song.Exists(decodedSongID))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            Song song = new Song(decodedSongID);
            SyndicationFeed feed = new SyndicationFeed();
            string title = song.Title;

            if (song.Artist != null)
            {
                title = song.Artist + " - " + title;
            }

            feed.Title = new TextSyndicationContent(title);
            feed.Description = new TextSyndicationContent(title);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/Song")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();
            SongSyndicationItem item = new SongSyndicationItem(song);
            items.Add(item);
            feed.Items = items;
            return Utility.GetFormatter(feed);
        }

        /// <summary>
        /// Gets a Stream of a song file.
        /// </summary>
        /// <param name="songID">The song identifier.</param>
        /// <returns>The Stream.</returns>
        public Stream GetSongFile(string songID)
        {
            string decodedSongID = HttpUtility.UrlDecode(songID);

            if (!Song.Exists(decodedSongID))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            Song song = new Song(decodedSongID);
            FileInfo songFile = new FileInfo(song.FileName);

            if (!songFile.Exists)
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return null;
            }

            WebOperationContext.Current.OutgoingResponse.ContentType = MimeType.FromExtension(songFile.Extension);
            WebOperationContext.Current.OutgoingResponse.ContentLength = songFile.Length;
            WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Disposition: attachment; filename=" + songFile.Name);
            return songFile.OpenRead();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="title"></param>
        /// <param name="artist"></param>
        /// <param name="albumTitle"></param>
        /// <param name="albumArtist"></param>
        /// <param name="genre"></param>
        /// <param name="year"></param>
        /// <param name="startIndex"></param>
        /// <param name="maxResults"></param>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public SyndicationFeedFormatter GetSongs(string title, string artist, string albumTitle, string albumArtist, string genre, string year, string startIndex, string maxResults, string orderBy)
        {
            string decodedTitle = title;

            if (title != null)
            {
                decodedTitle = HttpUtility.UrlDecode(title);
            }

            string decodedArtist = artist;

            if (artist != null)
            {
                decodedArtist = HttpUtility.UrlDecode(artist);
            }

            string decodedAlbumTitle = albumTitle;

            if (albumTitle != null)
            {
                decodedAlbumTitle = HttpUtility.UrlDecode(albumTitle);
            }

            string decodedAlbumArtist = albumArtist;

            if (albumArtist != null)
            {
                decodedAlbumArtist = HttpUtility.UrlDecode(albumArtist);
            }

            string decodedGenre = genre;

            if (genre != null)
            {
                decodedGenre = HttpUtility.UrlDecode(genre);
            }

            int parsedYear = 0;
            int.TryParse(year, out parsedYear);

            int parsedStartIndex = 0;
            int.TryParse(startIndex, out parsedStartIndex);

            int parsedMaxResults = 0;
            int.TryParse(maxResults, out parsedMaxResults);

            SongSortOrder order = SongSortOrder.Title;

            if (!string.IsNullOrEmpty(orderBy))
            {
                order = (SongSortOrder)Enum.Parse(typeof(SongSortOrder), orderBy, true);
            }

            List<Song> songs = Song.Search(decodedTitle, decodedArtist, decodedAlbumTitle, decodedAlbumArtist, decodedGenre, parsedStartIndex, parsedMaxResults, order);
            SyndicationFeed feed = new SyndicationFeed();

            string feedTitle = "Song search results";
            string feedDescription = "Search results for songs in the Windows Media Player library";

            if (decodedTitle == null && decodedArtist == null && decodedAlbumTitle == null && decodedAlbumArtist == null && decodedGenre == null && parsedStartIndex == 0 && parsedStartIndex == 0 && parsedMaxResults == 0)
            {
                feedTitle = "All Songs";
                feedDescription = "All songs in the Windows Media Player library";
            }

            feed.Title = new TextSyndicationContent(feedTitle);
            feed.Description = new TextSyndicationContent(feedDescription);
            feed.Links.Add(SyndicationLink.CreateAlternateLink(new Uri("http://code.google.com/p/mediafeeder/wiki/Songs")));
            feed.Generator = XmlString.Generator;
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.ITunesLocalName, XmlString.GenericNameSpace), XmlString.ITunesNamespace);
            feed.AttributeExtensions.Add(new XmlQualifiedName(XmlString.MediaFeederLocalName, XmlString.GenericNameSpace), XmlString.MediaFeederNamespace);
            List<SyndicationItem> items = new List<SyndicationItem>();

            foreach (Song song in songs)
            {
                if (parsedYear != 0 && song.Year != parsedYear)
                {
                    SongSyndicationItem item = new SongSyndicationItem(song);
                    items.Add(item);
                }
            }

            feed.Items = items;
            return Utility.GetFormatter(feed);

        }

        /// <summary>
        /// Plays the specified song.
        /// </summary>
        /// <param name="songID">The song identifier.</param>
        /// <returns></returns>
        public void PlaySong(string songID)
        {
            string decodedSongID = HttpUtility.UrlDecode(songID);

            if (!Song.Exists(decodedSongID))
            {
                WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
                return;
            }

            Song song = new Song(decodedSongID);
            song.Play();
        }
    }
}
